package test.groovy
/*
class Example {

    static void main(String[] args) {
        String str = '''<collection shelf='New Arrivals' ss='ss'>
  <movie title='Enemy Behind' />
  <type aa='aa' bb='bb'>War, Thriller</type>
  <format>DVD</format>
  <year>2003</year>
  <rating>PG</rating>
  <aa>PG</aa>
  <stars>10</stars>
  <description>Talk about a US-Japan war</description>
</collection>'''
        def parser = new XmlParser()
        def doc = parser.parseText(str);
        def object = doc.type[0]
        println object['@aa']
        println object['@bb']
        println object.text()
    }
}*/

/*
class POGO implements GroovyInterceptable {
//GroovyInterceptable  invokeMethod死循环了
// System.out.println 不是println 看源码就明白了

    private String field
    String property1

    void setProperty1(String property1) {
        this.property1 = "setProperty1"
    }

    void display() {
        System.out.println "display"
    }

    void display(arg) {
        System.out.println "display"
    }

    def methodMissing(String name, def args) {
        System.out.println "methodMissing(${name},  ${args}) "
    }

    def invokeMethod(String s, Object o) {
        System.out.println "invokeMethod(${s}, Object ${o}) "
        System.out.println(metaClass)
//        super.invokeMethod(s,o) //也会死循环
//        def method = metaClass.getMetaMethods()
//        System.out.println method
        def method1 = metaClass.getMetaMethod(s, o)
        if (method1 == null) {
            System.out.println("invokeMethod not found")
        } else {
            method1.invoke(this, o)// 为何此处getMetaMethod返回的是空对象  //
        }
    }
}


def pogo = new POGO()
pogo.property1 = "aa"
println pogo.field
println pogo.property1
pogo.metaClass.setAttribute(pogo, 'field', 'ha')
pogo.metaClass.setAttribute(pogo, 'property1', 'ho') //并未调用setProperty1的方法

*/
/*pogo.metaClass.setProperty = { String var1, Object var2 ->
    System.out.println "${var1} ${var2}"
}*//*

pogo.metaClass.setAttribute(pogo, 'field', 'ha')
pogo.metaClass.setAttribute(pogo, 'property1', 'ho') //并未调用setProperty1的方法
println pogo.property1
println pogo.field == 'ha'
println pogo.property1 == 'ho'

pogo.metaClass.invokeMethod = { String name, Object args ->
    System.out.println "metaClass.invokeMethod ${name} ${args}"
}
pogo.display()
pogo.metaClass.display2 << { ->
    System.out.println "metaClass.display2"
}
pogo.display2()


println "-----------------"

class POGO2 implements GroovyInterceptable {
    def invokeMethod(String s, Object o) {
        System.out.println "invokeMethod(${s}, Object ${o}) "
        metaClass.getMetaMethod(s, o).invoke(this, o)
    }

    def display() {
        System.out.println "display"
    }

    def methodMissing(String name, def args) {
        System.out.println "methodMissing(${name},  ${args}) "
    }
}

new POGO2().display()



println "-----------------------"

class Person implements GroovyInterceptable {
    def invokeMethod(String name, Object args) {
        System.out.println "called invokeMethod $name $args"
        metaClass.getMetaMethod(name, args).invoke(this, args)
    }

    def greet() {
        System.out.println "Hello from greet()"
    }
}

def p = new Person()
p.greet()
println "----------------------"

use(TimeCategory, ServletCategory) {
    println 1.minute.from.now
    println 10.hours.ago

    def someDate = new Date()
    println someDate - 3.months
}
println "------------------"
//@Category(Number)
class NumberCategory {
    public static String getMeters(Integer num) {
        "${num} m"
    }
}

use(NumberCategory) {
    println 42.meters
}

@Category(Number)
//static 方法的第一个参数可不写了
class NumberCategory2 {
    String getMeters() {
        "${this} m"
    }
}

use(NumberCategory2) {
    println 42.meters
}
println "-----------------"

int i = 0
5.maxRetries {
    i++
}
println i == 1
i = 0
try {
    5.maxRetries {
        throw new RuntimeException("oops")
    }
} catch (RuntimeException e) {
    println i == 5
}
def str = "bb";
println String.greeting()
println str.greeting2()
println str.greeting()*/

class Stuff {
    static invokeMe() { "foo" }
}
Stuff.metaClass.'static'.invokeMethod = { String name, args ->
    def metaMethod = Stuff.metaClass.getStaticMetaMethod(name, args)
    def result
    if(metaMethod) result = metaMethod.invoke(delegate,args)
    else {
        result = "bar"
    }
    result
}
println "foo" == Stuff.invokeMe()
println "bar" == Stuff.doStuff()